import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Calendar;

public class Libro extends Item{
	private BigInteger isbn;
	private String titulo;
	private int anioPublicacion;
	private Editorial editorial;
	private Tipo tipo;
	private ArrayList<Prestamo> listaPrestamos = new ArrayList<Prestamo>();
	
	//getters and setters
	public BigInteger getIsbn() {
		return isbn;
	}
	private void setIsbn(BigInteger isbn) {
		this.isbn = isbn;
	}
	public String getTitulo() {
		return titulo;
	}
	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}
	public int getAnioPublicacion() {
		return anioPublicacion;
	}
	public void setAnioPublicacion(int anioPublicacion) {
		this.anioPublicacion = anioPublicacion;
	}
	public Editorial getEditorial() {
		return (Editorial) editorial.clone();
	}
	public void setEditorial(Editorial editorial) {
		this.editorial = editorial;
	}
	public Tipo getTipo() {
		return (Tipo) tipo.clone();
	}
	public void setTipo(Tipo tipo) {
		this.tipo = tipo;
	}
	private ArrayList<Prestamo> getListaPrestamos() {
		return listaPrestamos;
	}

	
	//Constructor
	public Libro(BigInteger isbn, String titulo, int anioPublicacion,Editorial editorial, Tipo tipo ){
		this.modificar(isbn, titulo, anioPublicacion, editorial, tipo);
	}
	
	// Metodos
	public boolean modificar(BigInteger isbn, String titulo, int anioPublicacion,Editorial editorial, Tipo tipo ){
		if (editorial.estaHabilitado() && tipo.estaHabilitado()) {
			this.setIsbn(isbn);
			this.setTitulo(titulo);
			this.setAnioPublicacion(anioPublicacion);
			this.setEditorial(editorial);
			this.setTipo(tipo);
			this.habilitar();
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public ArrayList<Usuario> buscarInfractores() {
		
		ArrayList<Usuario> infractores = new ArrayList<Usuario>();
		boolean repetido;
		Calendar hoy = Calendar.getInstance();
		//hoy.add(Calendar.DAY_OF_MONTH, 3); // Solo para un debug mas rapido, modificamos la fecha de hoy
		
		for (Prestamo prestamoActual : this.getListaPrestamos()) {
			if((prestamoActual.estaHabilitado())&&(prestamoActual.getFechaFin().before(hoy))){
				//Recorremos el array que retornaremos para asegurarnos que no se repita el usuario
				repetido = false;
				for (Usuario usuarioActual : infractores) {
					if(prestamoActual.getUsuario()==usuarioActual){repetido=true;}
				}
				
				if(!repetido){
					prestamoActual.getUsuario().deshabilitar();
					infractores.add(prestamoActual.getUsuario());
					};
			}
		}
		return infractores;
	}
	
	public void imprimirDatos(){
		System.out.println("\nDatos del Libro que posea Isbn: "+this.getIsbn());
		System.out.println("\tTitulo: "+this.getTitulo());
		System.out.println("\tEstado: "+this.estaHabilitadoTexto());
		System.out.println("\tDisponible: "+ this.disponiblePrestamosTexto());
		System.out.println("\tAño De Publicación: "+this.getAnioPublicacion());
		System.out.println("\tEditorial: "+this.getEditorial().getIdentificador()+" | "+this.getEditorial().getNombre());
		System.out.println("\tTipo: "+this.getTipo().getCodigo()+" | "+this.getTipo().getDescripcion());

		System.out.println("\n\tPrestamos Realizados:");
		
		for (Prestamo actual : listaPrestamos) {
			System.out.println("");
			actual.mostrarDatos();
		}
		
	}
	public Prestamo realizarPrestamo(Usuario usuario){
		if(this.estaHabilitado() && this.disponiblePrestamos() && usuario.estaHabilitado()){
			Prestamo prestamo = new Prestamo(usuario);			
			this.listaPrestamos.add(prestamo);
			return prestamo;
		}
		else
		{
			System.out.println("\nNo se pudo realizar el prestamo de "+ this.getTitulo() +". El usuario "+ usuario.getApellido()+", "+ usuario.getNombre() +" no esta habilitado o bien el libro no esta habilitado o disponible.");
			return null;
		}
	}
	
	public int cantidadPrestamos(){		
		return this.listaPrestamos.size();
	}	
	
	public void cancelarPrestamo(){
		if(!this.getListaPrestamos().isEmpty()){this.getListaPrestamos().get(0).cancelar();};
	}
	
	// Determina si el libro esta disponible para prestamos, que es en caso de que no haya prestamos o haya vencido el último prestamo
	public boolean disponiblePrestamos() {
		if(cantidadPrestamos()==0 ||(!this.getListaPrestamos().get(0).estaHabilitado())){
			return true;
		}
		else
		{
			return false;
		}
	}
	
	public String disponiblePrestamosTexto() {
		if(this.disponiblePrestamos()){
			return "Disponible";
		}
		else
		{
			return "No Disponible";
		}
	}
	

	public ArrayList<Prestamo> obtenerCopiaDePrestamos(){
		ArrayList<Prestamo> copiaPrestamos = new ArrayList<Prestamo>();
		
		for (Prestamo prestamoActual : this.getListaPrestamos()) {
			copiaPrestamos.add((Prestamo) prestamoActual.clone());
		}
		
		return copiaPrestamos;
	}
	
	public boolean equals(Libro libro){
		if(libro!=null){
			if(
				(this.estaHabilitado()==libro.estaHabilitado())
				&&
				(this.getIsbn().compareTo(libro.getIsbn())==0)
				&&
				(this.getAnioPublicacion()==libro.getAnioPublicacion())
				&&
				(this.getTitulo().compareTo(libro.getTitulo())==0)
				&&
				(this.getEditorial().equals(libro.getEditorial()))
				&&
				(this.getTipo().equals(libro.getTipo()))
				&&
				(this.getListaPrestamos().equals(this.getListaPrestamos()))
			){
				return true;
			}
			else
			{
				return false;
			}
		}
		else
		{
			return false;
		}
	}
	
}
